package com.central.apps.handler.MaterialInventory;

import cn.hutool.core.map.MapUtil;
import com.central.app.common.base.BaseHandler;
import com.central.app.common.constant.AppConstant;
import com.central.app.common.util.BLuntil;
import com.central.app.service.HandlerService;
import com.central.apps.dao.MaterialInventory.CheckDao;
import com.central.apps.service.IInventoryService;
import com.central.bizcommon.model.flow.FlowNode;
import com.central.bizcommon.model.flow.FlowOpinion;
import com.central.common.web.PageResult;
import com.central.common.web.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.bouncycastle.asn1.x500.style.RFC4519Style.o;

/**
 * 库存盘点
 */
@Slf4j
@Component
public class CheckHandler extends BaseHandler {
    @Autowired
    private HandlerService handlerService;
    @Autowired
    private CheckDao checkDao;
    @Autowired
    private IInventoryService iInventoryService;
    @Override
    public Object operate(String app, String type, Map<String, Object> params) throws Exception {
        String storenum = MapUtils.getString(params, "kid");   //库房编号
        String checkid = MapUtils.getString(params, "id");     //盘点id
        //根据选择领料单，带出领料子表
        if("getItem".equals(type)){
            String sql="select * from bl_inventorys where warehousenum='"+storenum+"'";
            return BLuntil.toPage(params,handlerService,sql);
        }
        //增加””按钮，用户点击后可一次性将用户在主表所选仓库中库存余量大于0的数据写入到盘点明细中
        if ("extractInventory".equals(type)) {
            //查询库存盘点的 盘点人和盘点时间，带入到盘点明细中
            String sqlcheck = "select * from gq_check where id ='"+checkid+"'";
            List<Map<String, Object>> checkList = handlerService.findBySql(sqlcheck);
            if (CollectionUtils.isNotEmpty(checkList)) {
                String id = MapUtils.getString(params, "id");
                List<Map<String, Object>> kcpdzbList = checkDao.getKcpdzbList(storenum);
                if (CollectionUtils.isNotEmpty(kcpdzbList)) {
                    //先删除
                    checkDao.delKcpdzbList(id);
                    for (int i = 0; i < kcpdzbList.size(); i++) {
                        Map<String, Object> kcpdzbMap = kcpdzbList.get(i);
                        //解决盘点提取库存单价列显示NaN问题
                        if(StringUtils.isBlank(MapUtils.getString(kcpdzbMap,"avgcost"))){
                            kcpdzbMap.put("avgcost",0);
                        }
                        kcpdzbMap.put("pidd", id);
                        kcpdzbMap.put("checker", checkList.get(0).get("Checkperson"));
                        kcpdzbMap.put("Invtime", checkList.get(0).get("Ptime"));
                        kcpdzbMap.put("pidd", id);
                        kcpdzbMap.put("delflag","0");
                        kcpdzbMap.put("checkqty",0);
                        kcpdzbMap.put("createuser",checkList.get(0).get("createuser"));
                        kcpdzbMap.put("deptcode",checkList.get(0).get("deptcode"));
                        kcpdzbMap.put("linecost",0f);
                        checkDao.insertKcpdzb(kcpdzbMap);
                    }
                    //提取完后，变更buttonflag 按钮标识
                    handlerService.findBySql("update gq_check set buttonflag='success' where id='"+id+"'");
                    return Result.succeed(kcpdzbList, "成功");
                }
            }

        }
        if ("choiceInventory".equals(type)) {
            //增加”选择库存”按钮，可选择需要盘点的物资，用户批量选择物资后将点击确定按钮，将物资编码、描述、库位、批次写入到相应字段中，将余量写入到预盘数量中；
            List<Map<String, Object>> inventoryList = checkDao.getInventoryByStorenum(storenum, checkid);
            if (CollectionUtils.isNotEmpty(inventoryList)) {
                int page = 1;
                int limit = 10;
                if (MapUtils.getInteger(params, AppConstant.BIZ_QUERY_PAGE) != null && MapUtils.getInteger(params, AppConstant.BIZ_QUERY_LIMIT) != null) {
                    page = MapUtil.getInt(params, AppConstant.BIZ_QUERY_PAGE);
                    limit = MapUtil.getInt(params, AppConstant.BIZ_QUERY_LIMIT);
                }

                List<Map<String, Object>> collect = inventoryList.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
                return PageResult.<Map<String, Object>>builder().data(collect).code(0).count((long) inventoryList.size()).build();
            }
        }
        //库存盘点 选择物资 货位要加弹出框，展示主表库房下面的货位
        if("binnumPopup".equals(type)){
            List<Map<String, Object>> bySql = handlerService.findBySql("select shelfnum,shelfdesc from gq_areashelf where storenum = '" + storenum + "'");
            if(CollectionUtils.isNotEmpty(bySql)){
                int page = 1;
                int limit = 10;
                if (MapUtils.getInteger(params, AppConstant.BIZ_QUERY_PAGE) != null && MapUtils.getInteger(params, AppConstant.BIZ_QUERY_LIMIT) != null) {
                    page = MapUtil.getInt(params, AppConstant.BIZ_QUERY_PAGE);
                    limit = MapUtil.getInt(params, AppConstant.BIZ_QUERY_LIMIT);
                }

                List<Map<String, Object>> collect = bySql.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
                return PageResult.<Map<String, Object>>builder().data(collect).code(0).count((long) bySql.size()).build();
            }
        }
        return null;
    }

    @Override
    public String beforeExcuteFlow(String app, Long id, FlowNode flowNode, FlowOpinion op) throws Exception {
        if ("fqr".equals(flowNode.getId())){
            List<Map<String, Object>> bySql = handlerService.findBySql("select pidd,checkqty,counnot from gq_kcpdzb where pidd =" + id);
            if (CollectionUtils.isEmpty(bySql)){
                return "请添加物资盘点列表相关信息！";
            }else if (CollectionUtils.isNotEmpty(bySql)){
                // String instonum = MapUtils.getString(bySql.get(0),"instonum");
                List<Map<String, Object>> bySql3 = handlerService.findBySql("SELECT * from biz_attribute where object_id=(SELECT id from biz_object where name ='gq_kcpdzb') and required !=''");
                if (CollectionUtils.isNotEmpty(bySql3)){
                    for(int i=0;i<bySql3.size();i++){
                        Map<String, Object> map = bySql3.get(i);
                        String required = MapUtils.getString(map, "required");
                        if (required!=null||required!=""){
                            //log.info("required+++++++++++++++++++++++++++++++++++++" + required);
                            String columnname = MapUtils.getString(bySql3.get(i), "columnname");
                            // log.info("required+++++++++++++++++++++++++++++++++++++" + columnname);
                            List<Map<String, Object>> bySql4 = handlerService.findBySql("select "+columnname+" from gq_kcpdzb where pidd='" + id + "'");
                            if (CollectionUtils.isNotEmpty(bySql4)){
                                Map<String, Object> map1 = bySql4.get(0);
                                String columnname1 = MapUtils.getString(map1, columnname);
                                log.info("o+++++++++++++++++++++++++++++++++++++" + o);
                                if (StringUtils.isEmpty(columnname1)){
                                    log.info("required+++++++++++++++++++++++++++++++++++++" + columnname1);
                                    return "有必填信息未填，请继续填写!";
                                }else {
                                    log.info("required+++++++++++++++++++++++++++++++++++++" + columnname1);
                                }
                            }
                        }
                    }
                }
                for (int i=0;i<bySql.size();i++){
                    Map<String, Object> map = bySql.get(i);
                    Float checkqty = MapUtils.getFloat(map, "checkqty");
                    String counnot = MapUtils.getString(map, "counnot");//是否已盘
                    if(checkqty!=null){
                        if (checkqty<0){
                            return "盘点数量不能小于0，请重新填写！";
                        }
                    }else{
                        return "盘点数量不能为空，请重新填写！";
                    }
                    int inew = i+1;
                    if(StringUtils.isBlank(counnot) || "否".equals(counnot)){
                        return "盘点列表第"+inew+"行是否已盘未填写！";
                    }
                }
            }
        }
        return super.beforeExcuteFlow(app, id, flowNode, op);
    }

    @Override
    public void afterExcuteFlow(String app, Long id, FlowNode flowNode, FlowOpinion op, String event) throws Exception {
        if (flowNode.getId().equals("principal")){
            // 审核通过后退库库存
            boolean flag = op.isFlag();//判断是否审核通过
            if (flag){
                List<Map<String, Object>> bySql = handlerService.findBySql("select * from gq_check where id =" + id);
                String kid =MapUtils.getString(bySql.get(0),"kid");
                String pid = MapUtils.getString(bySql.get(0), "Pid");
                String miaoshu = MapUtils.getString(bySql.get(0), "MIAOSHU");
                String checkperson = MapUtils.getString(bySql.get(0), "Checkperson");
                String createuserdesc = MapUtils.getString(bySql.get(0), "createuserdesc");
                List<Map<String, Object>> bySql1 = handlerService.findBySql("select * from gq_kcpdzb where pidd =" + id);
                if (CollectionUtils.isNotEmpty(bySql1)){
                    for (int i=0;i<bySql1.size();i++){
                        Map<String, Object> map = bySql1.get(i);
                        String ITEMNUM =MapUtils.getString(map,"ITEMNUM");
                        String ITEMNAME =MapUtils.getString(map,"ITEMNAME");//物料名称
                        String lotnum =MapUtils.getString(map,"lotnum");//批次
                        Float checkqty =MapUtils.getFloat(map,"checkqty");
                        String binnum =MapUtils.getString(map,"binnum");
                        String checker = MapUtils.getString(map, "checker");
                        Float inventory = MapUtils.getFloat(map, "Inventory");
                        String unitcost = MapUtils.getString(map, "unitcost");
                        String invtime = MapUtils.getString(map, "Invtime");
                        Float linecost = MapUtils.getFloat(map, "linecost");//差异金额
                        Float differqty = MapUtils.getFloat(map, "differqty");//差异数量
                        Float differqtynew = Math.abs(differqty);
                        String proid = MapUtils.getString(map, "proid");
                        String taskid = MapUtils.getString(map, "taskid");
                        String deptcode = MapUtils.getString(map, "deptcode");
                        String createuser = MapUtils.getString(map, "createuser");
                        //解决任务id不是必填的。有的数据根据任务id查不出来
                        List<Map<String,Object>> bySql2 = new ArrayList<>();
                        if(StringUtils.isNotBlank(taskid)){
                            bySql2 = handlerService.findBySql("select * from gq_invbalances where storenum ='" + kid + "' and itemnum ='" + ITEMNUM + "' and batchnum ='"+lotnum+"' and binnum ='"+binnum+"' and proid='"+proid+"' and taskid ='"+taskid+"'");
                        }else{
                            bySql2 = handlerService.findBySql("select * from gq_invbalances where storenum ='" + kid + "' and itemnum ='" + ITEMNUM + "' and batchnum ='"+lotnum+"' and binnum ='"+binnum+"' and proid='"+proid + "'");
                        }
                        if(CollectionUtils.isNotEmpty(bySql2)){
                            Float reservedqty = MapUtils.getFloat(bySql2.get(0), "reservedqty");
                            Float avblbalance1 = MapUtils.getFloat(bySql2.get(0), "avblbalance");
                            //float avblbalance =checkqty -reservedqty;
                            if(StringUtils.isNotBlank(taskid)){
                                handlerService.updateBySql("update gq_invbalances set avblbalance="+checkqty+",curbal="+checkqty+" where storenum ='" + kid + "' and itemnum ='" + ITEMNUM + "' and batchnum ='"+lotnum+"' and binnum ='"+binnum+"' and proid='"+proid+"' and taskid ='"+taskid+"'");
                            }else{
                                handlerService.updateBySql("update gq_invbalances set avblbalance="+checkqty+",curbal="+checkqty+" where storenum ='" + kid + "' and itemnum ='" + ITEMNUM + "' and batchnum ='"+lotnum+"' and binnum ='"+binnum+"' and proid='"+proid + "'");
                            }
                        }

                        List<Map<String, Object>> bySql6 = handlerService.findBySql("select * from gq_invbalances where  itemnum  ='" + ITEMNUM + "'and storenum ='" + kid + "'");
                        float curbal = 0;//库存余量
                        float avblbalance1 = 0;//可用余量
                        if (CollectionUtils.isNotEmpty(bySql6)){
                            for (Map<String,Object> objectMap :bySql6){
                                Float curbal1 = MapUtils.getFloat(objectMap, "curbal");
                                curbal = curbal+curbal1;//库存余量
                                Float avblbalance2 = MapUtils.getFloat(objectMap, "avblbalance");
                                avblbalance1 = avblbalance1+avblbalance2;//库存可用余量
                            }
                            handlerService.updateBySql("update gq_inventory set curbaltotal = " + curbal + ", avblbalance = " + avblbalance1 +  " where storenum = '" + kid + "' and itemnum = '" + ITEMNUM + "'");
                        }
                        //判个null
                        String warehousingCode = warehousingCode();//入库记录编码
                        String outboundCode = outboundCode();//出库记录编码
                        if(StringUtils.isNotBlank(MapUtils.getString(map, "linecost"))){
                            if (linecost>0){
                                //盘盈
                                handlerService.updateBySql("insert into gq_matusetrans (checknum,instonum,storenum,instodesc,itemnum,curbal,checkqty,checker,createtime,type,unitcost,linecost,proid,taskid,deptcode,createuser,quantity,lotnum) values('"+pid+"','"+warehousingCode+"','"+kid+"','"+miaoshu+"','"+ITEMNUM+"',"+inventory+","+checkqty+",'"+createuserdesc+"','"+invtime+"','盘盈',"+unitcost+","+linecost+",'"+proid+"','"+taskid+"','"+deptcode+"','"+createuser+"','"+differqtynew+"','"+lotnum+"')");

                            }else if (linecost<0){
                                //盘亏
                                handlerService.updateBySql("insert into gq_matusetrans (checknum,instonum,storenum,instodesc,itemnum,curbal,checkqty,checker,createtime,type,unitcost,linecost,proid,taskid,deptcode,createuser,quantity,lotnum) values('"+pid+"','"+outboundCode+"','"+kid+"','"+miaoshu+"','"+ITEMNUM+"',"+inventory+","+checkqty+",'"+createuserdesc+"','"+invtime+"','盘亏',"+unitcost+","+linecost+",'"+proid+"','"+taskid+"','"+deptcode+"','"+createuser+"','"+differqtynew+"','"+lotnum+"')");

                            }
                        }

                        //判断盘点的数量是否和库存数量一致，不一致的话，往盘点差异记录里记录
                        BigDecimal bigDecimalBig = new BigDecimal(String.valueOf(checkqty));
                        BigDecimal inventoryBig = new BigDecimal(String.valueOf(inventory));
                        if (bigDecimalBig.compareTo(inventoryBig) != 0) {
                            //盘点数和库存数不一致
                            Map<String, Object> inventoryRrecordMap = new HashMap<>();
                            inventoryRrecordMap.put("checkid", id);
                            inventoryRrecordMap.put("itemnum", ITEMNUM);
                            inventoryRrecordMap.put("itemname", ITEMNAME);
                            inventoryRrecordMap.put("Inventory", inventory);//库存
                            inventoryRrecordMap.put("inventorycount", checkqty);
                            inventoryRrecordMap.put("lotnum", lotnum);
                            inventoryRrecordMap.put("deptcode",deptcode);
                            inventoryRrecordMap.put("createuser",createuser);
                            //增加差异类型，差异数量
                            if(linecost>0f){
                                inventoryRrecordMap.put("differencetype","盘盈");
                            }else{
                                inventoryRrecordMap.put("differencetype","盘亏");
                            }
                            BigDecimal subtract = inventoryBig.subtract(bigDecimalBig);
                            inventoryRrecordMap.put("differencenumber",subtract.toString());
                            handlerService.insert("gq_inventoryRrecord", inventoryRrecordMap);
                        }
                    }
                }

            }
        }
    }

    private String outboundCode() {
        String outonumNew="";//出库编号
        List<Map<String, Object>> bySql9 = handlerService.findBySql("SELECT instonum from gq_matusetrans where instonum  LIKE '%CDFO%' order by instonum desc limit 1");
        if(CollectionUtils.isNotEmpty(bySql9)){
            Map<String, Object> map1 = bySql9.get(0);
            String instonum = MapUtils.getString(map1, "instonum");
            int integer = Integer.valueOf(instonum.substring(instonum.length() - 8));
            integer++;
            outonumNew="CDFO"+integer;
        }else{
            outonumNew="CDFO10000001";
        }
        return outonumNew;
    }

    private String warehousingCode() {
        String instonumNew="";//入库编号
        List<Map<String, Object>> bySql7 = handlerService.findBySql("SELECT instonum from gq_matusetrans where instonum  LIKE '%CDFI%' order by instonum desc limit 1");
        if(CollectionUtils.isNotEmpty(bySql7)){
            Map<String, Object> map7 = bySql7.get(0);
            String instonum1 = MapUtils.getString(map7, "instonum");
            int integer = Integer.valueOf(instonum1.substring(instonum1.length() - 8));
            integer++;
            instonumNew="CDFI"+integer;
        }else{
            instonumNew="CDFI10000001";
        }
        return instonumNew;
    }

    @Override
    public void afterSave(String app, String objName, Map<String, Object> data, boolean isUpdate) throws Exception {
        if ("checkApp".equals(app)) {
            if ("gq_kcpdzb".equals(objName)) {
                String pidd = MapUtils.getString(data, "pidd");
                //查子表  计算差异总金额 和差异总数量
                DecimalFormat decimalFormat = new DecimalFormat("##0.00");
                BigDecimal totalcostBD = new BigDecimal("0");
                Integer totalqty = 0;
                List<Map<String, Object>> kcpdzbListById = checkDao.getKcpdzbListById(pidd);
                for (int i = 0; i < kcpdzbListById.size(); i++) {
                    Map<String, Object> kcpdzbMap = kcpdzbListById.get(i);
                    String linecost = MapUtils.getString(kcpdzbMap, "linecost");
                    linecost = (linecost == null ? "0" : linecost);
                    linecost = (linecost.equals("") ? "0" : linecost);
                    Integer differqty = MapUtils.getInteger(kcpdzbMap, "differqty");
                    differqty = (differqty == null ? 0 : differqty);
                    BigDecimal linecostBD = new BigDecimal(linecost);
                    totalqty = totalqty + differqty;
                    totalcostBD = totalcostBD.add(linecostBD);

                    //差异金额为null  计算一下修改子表
                    String linecost1 = MapUtils.getString(kcpdzbMap, "linecost");
//                    if(StringUtils.isBlank(linecost1)){
//                        String checkqty = MapUtils.getString(kcpdzbMap, "checkqty");//盘点数量
//                        String Inventory = MapUtils.getString(kcpdzbMap, "Inventory");//库存数量
//                        String unitcost = MapUtils.getString(kcpdzbMap, "unitcost");//单价
//                        BigDecimal checkqtyBig = new BigDecimal(checkqty);
//                        BigDecimal subtract = checkqtyBig.subtract(new BigDecimal(Inventory));
//                        BigDecimal multiply = subtract.multiply(new BigDecimal(unitcost));
//                        String id = MapUtils.getString(kcpdzbMap, "id");
//                        handlerService.findBySql("update gq_kcpdzb set linecost = '" + multiply.toString() + "' where id = '" + id + "'");
//                    }
                }
                String totalcost = decimalFormat.format(totalcostBD);
                //修改主表
                checkDao.updateCheck(pidd, totalcost, totalqty);
            }
        }
    }

    @Override
    public void beforDelete(String app, String objName, Long id, boolean isLogic) {
        if ("checkApp".equals(app)) {
            if ("gq_kcpdzb".equals(objName)) {
                //删除之前更新盘点的差异总金额 和差异总数量
                Map<String, Object> kcpdzbById = checkDao.getKcpdzbById(id);
                String pidd = MapUtils.getString(kcpdzbById, "pidd");
                String linecostStr = MapUtils.getString(kcpdzbById, "linecost");
                linecostStr = linecostStr == null ? "0" : linecostStr;
                linecostStr = linecostStr.equals("") ? "0" : linecostStr;
                float linecost = Float.parseFloat(linecostStr);
                Integer differqty = MapUtils.getInteger(kcpdzbById, "differqty");
                differqty = (differqty == null ? 0 : differqty);
                checkDao.updateCheckTotal(pidd, linecost, differqty);
            }
        }
    }

    @Override
    public void addFlowVar(String app, Long id, FlowNode flowNode, FlowOpinion op, Map<String, Object> variables) throws Exception {
        if (app.equals("checkApp")) {
            if (flowNode.getId().equals("pd3")) {
                String changeby = MapUtils.getString(variables, "changeby");
                if ("10010".equals(changeby)) {
                    variables.put("ismat",0);
                }else {
                    variables.put("ismat",1);
                }
            }
        }
    }

    @Override
    public void beforSave(String app, String objName, Map<String, Object> data, boolean isUpdate) throws Exception {
        if ("checkApp".equals(app)){
            if (isUpdate==false){
                if ("gq_check".equals(objName)){
                    log.info("+++++++++++++++++++++++++++++++++++++++++="+data);
                    String status = MapUtils.getString(data, "status");
                    if (status.equals("会签成功")){
                        log.info("+++++++++++++++++++++++++++++++++++++++++="+status);
                    }
                }
            }
        }
        super.beforSave(app, objName, data, isUpdate);
    }
}
